package com.mimo.comet.provider.command.echo;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
import com.mimo.comet.provider.command.echo.BaseEchoCommand.EchoTypeIdResolver;
import com.mimo.common.utils.JsonUtils;
import com.mimo.common.utils.RandomStringUtils;

import io.swagger.annotations.ApiModelProperty;

@JsonTypeInfo(use = Id.CUSTOM, include = As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonTypeIdResolver(EchoTypeIdResolver.class)
public abstract class BaseEchoCommand {

    @ApiModelProperty(value = "响应echo ID,由发送端进行维护,需要保证该字段的唯一性", required = true)
    protected String id;

    /**
     * 响应类型
     */
    @ApiModelProperty(value = "响应类型", required = true)
    protected EchoType type;

    /**
     * 针对于哪一个目标消息做的Echo
     */
    @ApiModelProperty(value = "针对于哪一个目标消息做的Echo", required = true)
    protected String target;

    /**
     * 发送Echo的时间点
     */
    @ApiModelProperty(value = "发送Echo的时间点", required = true)
    protected long timestamp;

    protected BaseEchoCommand() {
        super();
        this.id = RandomStringUtils.uniqueRandom();
        this.timestamp = System.currentTimeMillis();
    }

    public void setId(String id) {
        this.id = id;
    }

    public void setTarget(String target) {
        this.target = target;
    }

    public String getId() {
        return id;
    }

    public EchoType getType() {
        return type;
    }

    public String getTarget() {
        return target;
    }

    public long getTimestamp() {
        return timestamp;
    }

    @Override
    public String toString() {
        return JsonUtils.toJsonString(this);
    }

    /**
     * 自定义一个组件解析器，以便于存储和解析 JSON的动态反序列化
     * 
     * @author Hongyu
     */
    public static class EchoTypeIdResolver extends TypeIdResolverBase {

        @Override
        public String idFromValue(Object value) {
            return BaseEchoCommand.class.cast(value).getType().name();
        }

        @Override
        public String idFromValueAndType(Object value, Class<?> suggestedType) {
            return BaseEchoCommand.class.cast(value).getType().name();
        }

        @Override
        public Id getMechanism() {
            throw new UnsupportedOperationException();
        }

        @Override
        public JavaType typeFromId(DatabindContext context, String id) {
            return context.constructType(EchoType.valueOf(id).getCmdClz());
        }
    }
}
